<template>
  <div>
    <v-app-bar
      :clipped-left="$vuetify.breakpoint.lgAndUp"
      app
      color="white"
      height="54"
      light
      id="create-adticle-bar"
    >
      <v-toolbar-title
        color="#697bc1"
      >
        <span>写 文 章</span>
      </v-toolbar-title>

      <v-divider vertical
                 style="margin:0 8px 0 10px"
      ></v-divider>

      <v-btn @click="$router.push({name:'Index'})"
             text
             color="primary"
             small>
        返回首页
      </v-btn>

      <v-spacer></v-spacer>

      <v-btn @click="articleInfoDialogVisible=true" depressed outlined color="primary"
             style="margin-right: 14px">
        下一步
      </v-btn>

      <v-menu
        v-model="userMenu"
        absolute
        :close-on-content-click="false"
        :nudge-width="240"
        :position-y="49"
        origin="top right"
        transition="scale-transition"
      >
        <template v-slot:activator="{ on, attrs }">
          <v-btn
            icon
            large
            v-bind="attrs"
            v-on="on"
          >
            <v-avatar
              size="32px"
              item
            >
              <v-img
                src="https://ae01.alicdn.com/kf/Hb2a78048cbbb43998fa4ed3add74f57eC.jpg"
                alt="me"
              ></v-img>
            </v-avatar>
          </v-btn>
        </template>

        <v-card>
          <div class="d-flex flex-column align-center pa-3">
            <v-avatar
              size="70px"
              item
            >
              <v-img
                src="https://ae01.alicdn.com/kf/Hb2a78048cbbb43998fa4ed3add74f57eC.jpg"
                alt="me"
              ></v-img>
            </v-avatar>
            <v-chip
              class="mt-2"
              color="pink"
              label
              x-small
              dark
              style="font-size: 12px;font-weight: 400"
            >
              {{ user.userRole === 1 ? '游客' : '管理员' }}
            </v-chip>
            <span class="mt-1" style="font-size: 14px;font-weight: 600">{{ user.nickName }}</span>


            <!--            <div class="d-flex justify-center mt-1">-->
            <!--              &lt;!&ndash;              <v-btn class="ma-1" x-small outlined fab text>&ndash;&gt;-->
            <!--              &lt;!&ndash;                <v-icon color="#777">mdi-key</v-icon>&ndash;&gt;-->
            <!--              &lt;!&ndash;              </v-btn>&ndash;&gt;-->
            <!--              &lt;!&ndash;              <v-btn class="ma-1" x-small outlined fab text>&ndash;&gt;-->
            <!--              &lt;!&ndash;                <v-icon color="#777">mdi-chat</v-icon>&ndash;&gt;-->
            <!--              &lt;!&ndash;              </v-btn>&ndash;&gt;-->
            <!--              <v-btn class="ma-1" x-small outlined fab text>-->
            <!--                <v-icon color="#777">mdi-dots-horizontal</v-icon>-->
            <!--              </v-btn>-->
            <!--            </div>-->

          </div>

          <div class="mb-1">
            <div class="pl-4 m-list-item none-select-css pa-1" v-ripple>
              <span>
                <v-icon small>mdi-account-circle-outline</v-icon>
              </span>
              <span style="font-size: 12px;">
                管理你的账户
              </span>
            </div>
          </div>
          <v-divider></v-divider>

          <v-card-actions>
            <v-spacer></v-spacer>
            <v-btn outlined color="#777" x-small @click="signOut">登出</v-btn>
          </v-card-actions>
        </v-card>
      </v-menu>
    </v-app-bar>

    <v-main>
      <v-container
        fluid
      >
        <div class="editor-section">
          <div class="article-title-edit-wrapper">
            <textarea rows="1"
                      ref="titleInputRef"
                      class="Input"
                      placeholder="请输入标题（最多 50 个字）"
                      @input="handleTextareaChange"
                      v-model="article.title"
                      :style="{height:titleTextareaHeight+'px'}"></textarea>
          </div>
          <div class="title-length-limit">
            还可以输入{{ titleMaxLength - currentTitleLength }}个字
          </div>

          <div class="cover-box" @click.stop="$refs.mlUpload.click()">
            <div class="cover-upload-box">
              <input type="file" ref="mlUpload"
                     accept="image/jpeg, image/jpg, image/png, image/bmp"
                     @change="handleUploadChange"
                     class="uploadcoverInput">
              <div class="no-img" v-if="!article.cover">
                <i class="icon-font icon-add-img"></i>
                <h4>请添加专栏头图（选填）</h4>
                <p class="tips">支持1MB内的JPG／JPEG／BMP／PNG格式的高清图片</p>
                <div class="img-box" style="display: none;">
                  <img src="" alt="" style="display: none;">
                  <div class="cover-loading">
                    <i class="icon-waiting"></i>
                  </div>
                  <div class="control-group clearfix">
                    <button class="re-upload left"><i class="icon-font icon-icon_upload"></i></button>
                    <button class="delete left"><i class="icon-font icon-delete"></i></button>
                  </div>
                </div>
                <!--模态框-->
                <div data-v-c11820e6="" class="bili-modal cropper-modal" style="display: none;">
                  <div data-v-c11820e6="" class="overlay"></div>
                  <div data-v-c11820e6="" class="modal">
                    <div data-v-c11820e6="" class="modal-head">
                      <div data-v-c11820e6="" class="head-wrap">设置文章头图</div>
                      <i data-v-c11820e6="" class="icon-font icon-close"></i></div>
                    <div data-v-c11820e6="" class="modal-content clearfix">
                      <div data-v-c11820e6="" class="img-clip-wrap">
                        <div data-v-c11820e6="" class="pre-info">截取展示区域</div>
                        <div data-v-c11820e6="" class="container-box">
                          <div data-v-c11820e6="" class="container-bg">
                            <div data-v-c11820e6="" class="img-container"><img data-v-c11820e6="">
                              <div data-v-c11820e6="" class="shadow-box"></div>
                              <div data-v-91f32c38="" data-v-c11820e6="" class="crop-wrap">
                                <div data-v-91f32c38="" class="shadow-box"><img data-v-91f32c38="" src=""
                                                                                class="shadow-img"></div>
                                <div data-v-91f32c38="" class="crop-box"></div>
                              </div>
                            </div>
                          </div>
                        </div>
                        <div data-v-c11820e6="" class="reset-img ui-btn grey-radius"><i data-v-c11820e6=""
                                                                                        class="icon reset-icon"></i>
                          <span
                            data-v-c11820e6="">重新选择</span> <input data-v-c11820e6="" type="file"
                                                                  accept="image/gif, image/jpeg, image/jpg, image/png, image/bmp"
                                                                  data-cover-retry=""></div>
                      </div>
                      <div data-v-c11820e6="" class="img-preview-wrap">
                        <div data-v-c11820e6="" class="pre-info">最终展示效果</div>
                        <div data-v-c11820e6="" class="pre-container"><img data-v-c11820e6=""></div>
                        <div data-v-c11820e6="" class="error-hint" style="display: none;"></div>
                      </div>
                    </div>
                    <div data-v-c11820e6="" class="modal-footer">
                      <button data-v-c11820e6="" class="ui-btn blue-radius">确认</button>
                      <button data-v-c11820e6="" class="ui-btn grey-radius">取消</button>
                    </div>
                  </div>
                </div>
              </div>
              <div v-else style="position: relative" @click.stop>
                <img :src="article.cover" style="max-height: 320px;" alt="">
                <span
                  style="position:absolute;right: 0;bottom: 0;width: 48px;height: 48px;padding: 6px;border-radius: 4px;background-color: rgba(26, 26, 26, 0.25)">
                  <img style="width: 100%;height: 100%;" src="/pic/image.png" alt="" @click="$refs.mlUpload.click()">
                </span>
              </div>
              <v-dialog v-model="showPreviewCover" persistent width="600" max-width="600">
                <v-card>
                  <v-card-title class="headline grey lighten-2">
                    裁剪图片
                  </v-card-title>
                  <div class="cut-pic-wrapper">
                    <img style="max-height: 300px;max-width: 500px" :src="coverBlobUrl" alt="" ref="previewPicture">
                  </div>
                  <v-divider></v-divider>

                  <v-card-actions>
                    <v-spacer></v-spacer>
                    <v-btn
                      color="primary"
                      @click="closeCutPictureModal"
                    >
                      取消
                    </v-btn>
                    <v-btn
                      color="success"
                      @click="handleCutPicture"
                    >
                      裁剪
                    </v-btn>
                  </v-card-actions>
                </v-card>

              </v-dialog>

            </div>
          </div>

          <textarea :id="ckId" placeholder="不辜负生命中的每一天..."></textarea>
          <div style="font-size: 12px;color: #99a2aa;text-align: right;margin:20px 0">
            已输入{{ wordCount }}字
          </div>
        </div>
      </v-container>
    </v-main>

    <v-fab-transition>
      <v-btn
        bottom
        color="pink"
        dark
        fab
        fixed
        right
        @click="goToTop"
        v-show="scrollTop>150"
      >
        <v-icon>mdi-chevron-up</v-icon>
      </v-btn>
    </v-fab-transition>

    <v-dialog v-model="articleInfoDialogVisible" persistent width="600" max-width="600">
      <v-card>
        <v-toolbar dark color="primary" height="54">
          <v-toolbar-title>文章设置</v-toolbar-title>
          <v-spacer></v-spacer>
          <v-toolbar-items>
            <v-btn icon dark @click="articleInfoDialogVisible = false">
              <v-icon>mdi-close</v-icon>
            </v-btn>
          </v-toolbar-items>
        </v-toolbar>

        <v-container>
          <v-subheader>选择一个合适的分类吧</v-subheader>
          <v-divider></v-divider>
          <v-row align="center">
            <v-col cols="12">
              <v-select
                v-model="article.category"
                :items="AllCategory"
                item-text="name"
                item-value="name"
                label="分类"
                multiple
                dense
                outlined
              >
                <template v-slot:selection="{ item }">
                  <v-chip
                    :color="`blue lighten-3`"
                    label
                    small
                  >
                      <span class="pr-2">
                        {{ item.name }}
                      </span>
                  </v-chip>
                </template>
              </v-select>
            </v-col>
          </v-row>

          <v-subheader>添加一些标签吧</v-subheader>
          <v-divider></v-divider>
          <v-row align="center">
            <v-col cols="12">

              <v-combobox
                v-model="article.tag"
                hide-selected
                label="添加标签"
                multiple
                outlined
                dense
                persistent-hint
                small-chips
              >
                <template v-slot:no-data>
                  <v-list-item>
                    <v-list-item-content>
                      <v-list-item-title>
                        按一下 <kbd>enter</kbd> 键创建一个标签吧
                      </v-list-item-title>
                    </v-list-item-content>
                  </v-list-item>
                </template>
                <template v-slot:selection="{ item }">
                  <v-chip
                    :color="`blue lighten-3`"
                    label
                    small
                  >
                      <span class="pr-2">
                        {{ item }}
                      </span>
                    <v-icon
                      small
                      @click="removeTag(item)"
                    >close
                    </v-icon>
                  </v-chip>
                </template>
              </v-combobox>
            </v-col>
          </v-row>

          <v-subheader>权限设置</v-subheader>
          <v-divider></v-divider>
          <v-row align="center">
            <v-col cols="12" sm="6">
              <v-select
                v-model="article.visiblePermission"
                :items="visiblePermission"
                label="隐私设置"
                item-text="name"
                dense
                outlined
              ></v-select>
            </v-col>
            <v-col cols="12" sm="6">
              <v-select
                v-model="article.replyPermission"
                :items="replyPermission"
                label="回复设置"
                item-text="name"
                dense
                outlined
              ></v-select>
            </v-col>
          </v-row>

        </v-container>
        <v-divider></v-divider>
        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn color="primary" text @click="articleInfoDialogVisible = false">返回编辑</v-btn>
          <v-btn color="success" @click="finishEditArticle">发布</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-overlay :value="loading" z-index="9999">
      <v-progress-circular indeterminate size="64"></v-progress-circular>
    </v-overlay>
  </div>
</template>

<script>
import { CreateArticle, GetAllCategory, GetArticle, UpdateOneArticle } from '../api/blog-api'
import UserMenuMixin from '../mixins/userMenuMixin'
import util from '../libs/util'
import { uploadImage } from '@/api/blog-api'

const PUBLISHED = 1
// const SERVER_ADDRESS = 'http://59.110.171.148/'
export default {
  name: 'EditArticle',
  mixins: [UserMenuMixin],
  data () {
    return {
      loading: true,
      article: {
        title: '',
        author: null,
        createTime: null,
        updateTime: null,
        viewNum: 0,
        content: '',
        cover: '',
        comments: [],
        visiblePermission: 0,
        replyPermission: 0,
        category: null,
        tag: null
      },
      coverBlobUrl: '',
      showPreviewCover: false,
      cropper: null,
      oldTag: [],
      ck: null,
      ckId: '',
      // 标题框高度
      titleTextareaHeight: 50,
      // 标题最长长度
      titleMaxLength: 50,
      // 当前标题长度
      currentTitleLength: 0,
      articleInfoDialogVisible: false,
      // 所有分类
      AllCategory: [],
      scrollTop: 0,
      visiblePermission: [
        {
          name: '所有人可见',
          value: 0
        },
        {
          name: '仅自己可见',
          value: 1
        }
      ],
      replyPermission: [
        {
          name: '所有人可回复',
          value: 0
        },
        {
          name: '不可回复',
          value: 1
        }
      ],
      wordCount: 0,
    }
  },
  created () {
    this.ckId = 'editor' + this.guid()
    this.getAllCategory()
  },
  mounted () {
    this.initEditor()
    window.addEventListener('scroll', this.scrollToTop)
  },

  beforeDestroy () {
    this.ck.destroy().then(res => {
      console.log(' Editor Destroyed')
    }).catch(error => {
      console.error('Destroy Editor Fail', error)
    })
    window.removeEventListener('scroll', this.scrollToTop)
  },

  methods: {
    guid () {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        const r = Math.random() * 16 | 0
        const v = c == 'x' ? r : (r & 0x3 | 0x8)
        return v.toString(16)
      })
    },

    // 裁剪图片
    handleCutPicture () {
      this.cropper.getCroppedCanvas({
        fillColor: '#fff',
        imageSmoothingEnabled: false,
      }).toBlob((blob) => {
        console.log(blob)
        const formData = new FormData()
        // Pass the image file name as the third parameter if necessary.
        formData.append('upload', blob/*, 'example.png' */)
        uploadImage(formData).then(res => {
          this.article.cover = res.data
        }).catch(err => {
          console.log(err)
        })
      }, 'image/jpeg')
      this.closeCutPictureModal()
    },

    closeCutPictureModal () {
      this.showPreviewCover = false
      this.coverBlobUrl = ''
      this.cropper.clear()
    },

    handleUploadChange (e) {
      let file = e.target.files[0]
      console.log(file)
      let KB = 1024
      if (file.size > 512 * KB) {
        this.$store.dispatch('milk/notice/push', {
          msg: '不支持大于512KB的图片',
          type: 'error'
        })
        return
      }

      this.coverBlobUrl = this.getObjectURL(file)
      console.log(this.coverBlobUrl)
      this.showPreviewCover = true
      this.$nextTick(() => {
        let image = this.$refs.previewPicture
        this.cropper = new Cropper(image, {
          guides: false,
          aspectRatio: 16 / 9,
        })
      })
    },

    getObjectURL (file) {
      var url = null
      if (window.createObjectURL !== undefined) { // basic
        url = window.createObjectURL(file)
      } else if (window.URL !== undefined) { // mozilla(firefox)
        url = window.URL.createObjectURL(file)
      } else if (window.webkitURL !== undefined) { // webkit or chrome
        url = window.webkitURL.createObjectURL(file)
      }
      return url
    },

    dataURLtoFile (dataurl, filename = 'file') {
      let arr = dataurl.split(',')
      let mime = arr[0].match(/:(.*?);/)[1]
      let suffix = mime.split('/')[1]
      let bstr = atob(arr[1])
      let n = bstr.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], `${filename}.${suffix}`, { type: mime })
    },

    // 获取所有分类
    getAllCategory () {
      GetAllCategory().then(res => {
        this.AllCategory = res.data
      }).catch(err => {
        console.log(err)
      })
    },

    // 获取滚动高度
    scrollToTop () {
      let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
      this.scrollTop = scrollTop
    },

    // 向上滚动到顶部
    goToTop () {
      document.querySelector('#app').scrollIntoView({ behavior: 'smooth' })
    },

    // 移除Tag
    removeTag (tagName) {
      this.article.tag.splice(this.article.tag.indexOf(tagName), 1)
    },
    initEditor () {
      let ClassicEditor = window.ClassicEditor
      if (ClassicEditor) {
        ClassicEditor.create(document.querySelector('#' + this.ckId), {
          toolbar: {
            viewportTopOffset: 54,
            items: [
              // 'heading',
              // '|',
              // 'fontSize',
              // 'fontColor',
              // 'fontBackgroundColor',
              // 'bold',
              // 'italic',
              // 'underLine',
              // 'strikeThrough',
              // 'blockQuote',
              // 'specialCharacters',
              // 'link',
              // 'bulletedList',
              // 'numberedList',
              // 'todoList',
              // '|',
              // 'indent',
              // 'outdent',
              // 'alignment',
              // '|',
              // 'code',
              // 'codeBlock',
              // 'imageUpload',
              // 'mediaEmbed',
              // 'insertTable',
              // 'undo',
              // 'redo',
              'heading',
              '|',
              'fontSize',
              'fontBackgroundColor',
              'fontColor',
              'bold',
              'italic',
              'link',
              'underline',
              'strikethrough',
              'blockQuote',
              'bulletedList',
              'numberedList',
              'todoList',
              'insertTable',
              '|',
              'indent',
              'outdent',
              'alignment',
              'horizontalLine',
              '|',
              'code',
              'codeBlock',
              'highlight',
              'specialCharacters',
              'imageUpload',
              'mediaEmbed',
              'undo',
              'redo'
            ]
          },
          language: 'zh-cn',
          image: {
            toolbar: [
              'imageTextAlternative',
              'imageStyle:full',
              'imageStyle:side'
            ]
          },
          link: {
            // Automatically add target="_blank" and rel="noopener noreferrer" to all external links.
            addTargetToExternalLinks: true,

            // Let the users control the "download" attribute of each link.
            decorators: [
              {
                mode: 'manual',
                label: 'Downloadable',
                attributes: {
                  download: 'download'
                }
              }
            ]
          },
          extraPlugins: [MyCustomUploadAdapterPlugin],
          table: {
            contentToolbar: [
              'tableColumn',
              'tableRow',
              'mergeTableCells',
              'tableCellProperties',
              'tableProperties'
            ]
          },
          wordCount: {
            onUpdate: stats => {
              this.wordCount = stats.characters
            }
          },
          licenseKey: ''
        }).then(editor => {
          this.ck = editor
          console.log(editor)
          let container = editor.ui.view.editable.element
          if (container) {
            container.addEventListener('keydown', (e) => {
              if (e.keyCode === 9) {
                console.log(e)
                const docFrag = editor.model.change(writer => {
                  const p1 = writer.createElement('paragraph')
                  const docFrag = writer.createDocumentFragment()
                  writer.append(p1, docFrag)
                  writer.insertText('    ', p1)
                  return docFrag
                })
                editor.model.insertContent(docFrag)
                e.preventDefault()
              }
            })
          }
          // 如果是编辑状态 获取并初始化文章信息
          if (this.$route.params.id) {
            this.getArticleInfo()
          } else {
            this.loading = false
          }
        }).catch(error => {
          console.error('Oops, something gone wrong!')
          console.error('Please, report the following error in the https://github.com/ckeditor/ckeditor5 with the build id and the error stack trace:')
          console.warn('Build id: 3gcylq8ef8o2-wfqspwcy9pd0')
          console.error(error)
        })
      } else {
        setTimeout(this.initEditor, 500)
      }
    },

    // 获取文章信息
    getArticleInfo () {
      let articleId = this.$route.params.id
      GetArticle({ _id: articleId }).then(res => {
        this.initArticleInfo(res.data[0])
      }).catch(err => {
        console.log(err)
      }).finally(() => {
        this.loading = false
      })
    },

    // 初始化文章信息
    initArticleInfo (article) {
      if (article.tag === null) article.tag = []
      this.article = article
      this.tagOld = article.tag
      this.ck.setData(this.article.content)
      // 需要更新一下标题的字数和高度
      this.$nextTick(() => {
        this.currentTitleLength = this.article.title.length
        if (this.titleTextareaHeight !== this.$refs.titleInputRef.scrollHeight) {
          this.titleTextareaHeight = e.target.scrollHeight
        }
      })
    },

    // 处理文章标题输入框发生变换
    handleTextareaChange (e) {
      if (e.target.value.length > this.titleMaxLength) {
        this.article.title = e.target.value.substring(0, 50)
      } else {
        this.currentTitleLength = e.target.value.length
      }

      if (this.titleTextareaHeight !== e.target.scrollHeight) {
        this.titleTextareaHeight = e.target.scrollHeight
      }
    },

    // 发布文章
    finishEditArticle () {
      // 获取文章相关信息
      let content = this.ck.getData()
      // console.log(this.article)
      this.article.content = content
      this.article.published = PUBLISHED
      this.loading = true
      if (this.article._id) {
        if (!this.article.author) {
          this.article.author = this.user._id
        }
        let result = this.diffArray(this.article.tag, this.oldTag)
        this.article.tagAdd = result.add
        this.article.tagRemove = result.remove
        // 编辑一个文章
        UpdateOneArticle(this.article).then(res => {
          this.initArticleInfo(res.data)
          this.loading = false
        }).catch(err => {
          console.log(err)
        }).finally(() => {
          this.articleInfoDialogVisible = false
          this.loading = false
        })
      } else {
        // 创建一个文章
        this.article.tagAdd = this.article.tag
        this.article.remove = []
        this.article.author = this.user._id
        CreateArticle([this.article]).then(res => {
          this.$store.dispatch('milk/notice/push', {
            msg: '发布成功',
            type: 'success'
          })
        }).catch(err => {
          console.log(err)
        }).finally(() => {
          this.articleInfoDialogVisible = false
          this.loading = false
        })
      }
      // this.$router.push({ path: '/' })
    },

    diffArray (newArray = [], oldArray = []) {
      newArray = newArray ? newArray : []
      oldArray = oldArray ? oldArray : []
      let result = {
        add: [],
        remove: []
      }
      let newArrayLength = newArray.length
      for (let i = 0; i < newArrayLength; i++) {
        let oldArrayLength = oldArray.length
        for (let j = 0; j < oldArrayLength; j++) {
          if (newArray[i] === oldArray[j]) {
            newArray.splice(i, 1)
            oldArray.splice(j, 1)
            newArrayLength--
            i--
            break
          }
        }
      }
      result.add = newArray
      result.remove = oldArray
      return result
    }
  }
}

class MyUploadAdapter {
  constructor (loader) {
    // The file loader instance to use during the upload.
    this.loader = loader
  }

  // Starts the upload process.
  upload () {
    return this.loader.file
      .then(file => new Promise((resolve, reject) => {
        this._initRequest()
        this._initListeners(resolve, reject, file)
        this._sendRequest(file)
      }))
  }

  // Aborts the upload process.
  abort () {
    if (this.xhr) {
      this.xhr.abort()
    }
  }

  // Initializes the XMLHttpRequest object using the URL passed to the constructor.
  _initRequest () {
    const xhr = this.xhr = new XMLHttpRequest()

    // Note that your request may look different. It is up to you and your editor
    // integration to choose the right communication channel. This example uses
    // a POST request with JSON as a data structure but your configuration
    // could be different.
    xhr.open('POST', process.env.VUE_APP_BASE_URL + 'file', true)
    xhr.responseType = 'json'
  }

  // Initializes XMLHttpRequest listeners.
  _initListeners (resolve, reject, file) {
    const xhr = this.xhr
    const loader = this.loader
    const genericErrorText = `Couldn't upload file: ${file.name}.`

    xhr.addEventListener('error', () => reject(genericErrorText))
    xhr.addEventListener('abort', () => reject())
    xhr.addEventListener('load', () => {
      const response = xhr.response

      // This example assumes the XHR server's "response" object will come with
      // an "error" which has its own "message" that can be passed to reject()
      // in the upload promise.
      //
      // Your integration may handle upload errors in a different way so make sure
      // it is done properly. The reject() function must be called when the upload fails.
      if (!response || response.error || response.code !== 200) {
        return reject(response && response.error ? response.error.message : genericErrorText)
      }

      // If the upload is successful, resolve the upload promise with an object containing
      // at least the "default" URL, pointing to the image on the server.
      // This URL will be used to display the image in the content. Learn more in the
      // UploadAdapter#upload documentation.
      resolve({
        default: response.data
      })
    })

    // Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
    // properties which are used e.g. to display the upload progress bar in the editor
    // user interface.
    if (xhr.upload) {
      xhr.upload.addEventListener('progress', evt => {
        if (evt.lengthComputable) {
          loader.uploadTotal = evt.total
          loader.uploaded = evt.loaded
        }
      })
    }
  }

  // Prepares the data and sends the request.
  _sendRequest (file) {
    const token = util.cookies.get('token')
    // Prepare the form data.
    const data = new FormData()
    data.append('upload', file)

    // 让每个请求携带token--
    if (token) {
      this.xhr.setRequestHeader('Authorization', 'Bearer ' + token)
    }
    // Important note: This is the right place to implement security mechanisms
    // like authentication and CSRF protection. For instance, you can use
    // XMLHttpRequest.setRequestHeader() to set the request headers containing
    // the CSRF token generated earlier by your application.

    // Send the request.
    this.xhr.send(data)
  }
}

// ...

function MyCustomUploadAdapterPlugin (editor) {
  editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
    // Configure the URL to the upload script in your back-end here!
    return new MyUploadAdapter(loader)
  }
}

function MyCustomTabPlugin (editor) {
  editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
    // Configure the URL to the upload script in your back-end here!
    return new MyUploadAdapter(loader)
  }
}

</script>

<style>
.editor-section {
  position: relative;
  max-width: 920px;
  margin: 0 auto;
}

.article-title-edit-wrapper {
  position: relative;
  margin-top: 20px;
  display: block;
  width: 100%;
  border: 0;
  font-size: 32px;
  font-weight: 600;
  font-synthesis: style;
  outline: none;
  -webkit-box-shadow: none;
  box-shadow: none;
}

/*.article-title-edit-wrapper .Input {*/
/*overflow: auto;*/
/*}*/

.Input {
  width: 100%;
  padding: 0;
  overflow: auto;
  background: transparent;
  border: none;
  outline: none;
  resize: none;
  /*border-bottom: 1px solid #dfdfdf;*/
}

textarea.Input {
  color: #1a1a1a;
}

.title-length-limit {
  margin-bottom: 14px;
  color: #8590a6;
  border-top: 1px solid #dfdfdf;
  font-size: 14px;
  text-align: right;
}

.cover-box {
  cursor: pointer;
  border-radius: 8px;
  margin: 24px auto;
  background-color: #fafbfd;
  color: #99a2aa;
  text-align: center;
  transition: .3s;
}

.cover-box:hover {
  box-shadow: 1px 1px 8px 0 #00000014;
}

.uploadcoverInput {
  display: none;
}

.no-img {
  padding: 36px 0;
}

.cut-pic-wrapper {
  display: grid;
  margin: 24px;
  place-items: center;
}

.editor-section .ck-content {
  border: none !important;
  box-shadow: 0 0 0 #ffffff !important;
  /*outline: none !important;*/
}

.editor-section .ck-toolbar {
  border-left: none !important;
  border-right: none !important;
}

.editor-section .ck.ck-toolbar {
  background-color: #ffffff !important;
}

.editor-section .ck.ck-toolbar__separator {
  margin-top: 6px !important;
  margin-bottom: 6px !important;
}
</style>
